package cn.ulc.socket.admin.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import cn.ulc.common.constant.enums.AvailableStatus;
import cn.ulc.common.util.CalendarUtil;
import cn.ulc.common.util.Result;
import cn.ulc.common.util.UserUtils;
import cn.ulc.socket.admin.model.dto.stat.HomeDTO;
import cn.ulc.socket.admin.model.dto.stat.MemberDTO;
import cn.ulc.socket.admin.model.dto.stat.MemberDataDTO;
import cn.ulc.socket.admin.service.member.MemberServ;
import cn.ulc.socket.admin.service.order.OrderServ;
import cn.ulc.socket.admin.service.user.WeixinUserServ;
import cn.ulc.store.entity.Company;
import cn.ulc.store.entity.user.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@RestController
@RequestMapping(value = "/stat")
public class StatCtrl {
    private static final Log log = LogFactory.get();
    @Autowired
    MemberServ memberServ;
    @Autowired
    OrderServ orderServ;
    @Autowired
    WeixinUserServ weixinUserServ;


    @GetMapping("/home")
    public Result findDetail(){
        //统计 今日 昨日 营业数据
        String todayBeginDate = DateUtil.format(DateUtil.beginOfDay(new Date()),"yyyy-MM-dd HH:mm:ss"),
            todayEndDate=DateUtil.format(new Date(),"yyyy-MM-dd HH:mm:ss");
        String yesterdayBeginDate = DateUtil.format(DateUtil.beginOfDay(DateUtil.yesterday()),"yyyy-MM-dd HH:mm:ss"),
            yesterdayEndDate=DateUtil.format(DateUtil.endOfDay(DateUtil.yesterday()),"yyyy-MM-dd HH:mm:ss");
        HomeDTO dto = new HomeDTO();
        Company company = (Company) UserUtils.getCompany();
        Map<String,Object> todayOrderStat = orderServ.findOrderStat(company.getId(),todayBeginDate,todayEndDate);
        Map<String,Object> yesterdayOrderStat = orderServ.findOrderStat(company.getId(),yesterdayBeginDate,yesterdayEndDate);
        Integer orderCount = (Integer) todayOrderStat.get("countTotal");
        //TODO 未完成
        dto.setTodayOrderStat(todayOrderStat);
        dto.setYesterdayOrderStat(yesterdayOrderStat);

        BigDecimal bd100 = BigDecimal.valueOf(100l);

        //会员统计
        Map<String,Object> todayMemberStat = memberServ.findStat(company.getId(),todayBeginDate,todayEndDate);
        Map<String,Object> yesterdayMemberStat = memberServ.findStat(company.getId(),yesterdayBeginDate,yesterdayEndDate);
        dto.setNewMemberCount(new HashMap<String,Object>(){{
            put("today",todayMemberStat.get("newCount"));
            put("yesterday",yesterdayMemberStat.get("newCount"));
        }});

        //会员订单饼图统计
        Map<String,Object> memberOrderStat = memberServ.findTodayOrderStat(company.getId());
        List<Map<String,Object>> memberOrderStatMap = new ArrayList<>();
        BigDecimal allOrderCount = BigDecimal.valueOf(orderCount);
        BigDecimal newMP = orderCount==0?BigDecimal.ZERO:
            BigDecimal.valueOf(Long.parseLong(memberOrderStat.get("newOrderCount").toString())).divide(allOrderCount,2, RoundingMode.HALF_UP).multiply(bd100);
        memberOrderStatMap.add(new HashMap<String,Object>(){{
            put("type","新增会员");
            put("count",memberOrderStat.get("newCount"));
            put("orders",memberOrderStat.get("newOrderCount"));
            put("proportion",newMP.toString());
        }});
        BigDecimal oldMP = orderCount==0?BigDecimal.ZERO:BigDecimal.valueOf(Long.parseLong(memberOrderStat.get("oldOrderCount").toString())).multiply(bd100).divide(allOrderCount,2, RoundingMode.HALF_UP);
        memberOrderStatMap.add(new HashMap<String,Object>(){{
            put("type","历史会员");
            put("count",memberOrderStat.get("oldCount"));
            put("orders",memberOrderStat.get("oldOrderCount"));
            put("proportion",oldMP.toString());
        }});
        BigDecimal allMP = orderCount==0?BigDecimal.ZERO:BigDecimal.valueOf(Long.parseLong(memberOrderStat.get("allOrderCount").toString())).multiply(bd100).divide(allOrderCount,2, RoundingMode.HALF_UP);
        memberOrderStatMap.add(new HashMap<String,Object>(){{
            put("type","全部会员");
            put("count",memberOrderStat.get("allCount"));
            put("orders",memberOrderStat.get("allOrderCount"));
            put("proportion",allMP.toString());
        }});
        dto.setMemberStat(memberOrderStatMap);

        return Result.success(dto);
    }


    @GetMapping("/member")
    public Result findMemberStat(String beginDate, String endDate){
        MemberDTO dto = new MemberDTO();
        Long totalCount = weixinUserServ.findCount();
        dto.setTotalCount(totalCount);
        Map<String,Object> orders = orderServ.findMemberStat(beginDate,endDate);
        dto.setOrders(orders);
        List<Map<String,Object>> consumeList = orderServ.findMemberRankingStat(beginDate,endDate);
        dto.setConsumeList(consumeList);
        return  Result.success(dto);
    }
    @GetMapping("/memberData")
    public Result findMemberDataStat(@Validated String type, String beginDate, String endDate){
        MemberDataDTO dto = new MemberDataDTO();
        //定义默认查询周期日期,legend名称
        Map<String,Object> result = getDefaultData(type,beginDate,endDate);
        String legend = "消费单数：";
        List<Object> volume = (List)result.get("volume");
        List<String> xData =  (List)result.get("xData");
        String cycleStr = (String)result.get("cycle");
        int diff = (int) result.get("diff");//记录索引与sql查询值的差
        List<Map<String,Object>> lineList = orderServ.findPeriodMemberStat(type,cycleStr,beginDate,endDate);
        if(lineList == null) lineList = new ArrayList<>();
        if(type.equals("custom") || type.equals("month") ){
            for (Map<String, Object> map : lineList) {
                Integer i =  xData.indexOf(map.get("cycle").toString());
                volume.set(i,map.get("count"));
            }
        }else{
            for (Map<String, Object> map : lineList) {
                int cycle = Integer.parseInt(map.get("cycle").toString());
                int index = cycle - diff;
                if(index < 0 || index >= volume.size()) continue;
                volume.set(index,map.get("count"));
            }
        }
        List<String> legendList = Arrays.asList(legend);
        Map<String,Object> memberOrderVolume = new HashMap<>();
        memberOrderVolume.put("legendData",legendList);
        memberOrderVolume.put("xData",xData);
        memberOrderVolume.put("seriesData",Arrays.asList(volume));
        memberOrderVolume.put("unit","单");
        dto.setMemberOrderVolume(memberOrderVolume);
        //客单价统计分布
        Map<String,Object> memberPrice = orderServ.findMemberOrder(beginDate,endDate);
        dto.setMemberPrice(memberPrice);
        return  Result.success(dto);
    }
    public Map<String,Object> getDefaultData(String type,String beginDate,String endDate){

        Map<String,Object> map = new HashMap<>();
        String legend = "今日";
        List<Object> volume = new ArrayList<>();
        List<String> xData =  new ArrayList<>();
        int diff = 0;//记录索引与sql查询值的差
        String cycle = "%H";
        switch (type){
            case "today":
                for(int i=0;i<24;i++){
                    xData.add(""+(i<9?0:"")+i+":00");
                    volume.add(0);
                }
                break;
            case "yesterday":
                for(int i=0;i<24;i++){
                    xData.add(""+(i<9?0:"")+i+":00");
                    volume.add(0);
                }
                legend = "昨日";
                break;
            case "week":
                cycle = "%w";
                for(int i=0;i<7;i++){
                    xData.add("周"+CalendarUtil.getWeekName(i));
                    volume.add(0);
                }
                legend = "本周";
                break;
            case "month":
                cycle = "%Y-%m-%d";
                diff = 1;
                String date = DateUtil.date().toString("yyyy-MM-");
                for(int i=0;i<DateUtil.dayOfMonth(DateUtil.date());i++){
                    if((i+1)<10){
                        xData.add(date+"0"+(i+1));
                    }else{
                        xData.add(date+(i+1));
                    }
                    volume.add(0);
                }
                legend = "本月";
                break;
            case "custom":
                cycle = "%Y-%m-%d";
                legend = "本周期";
                Date beginDt = DateUtil.parseDate(beginDate),endDt = DateUtil.parseDate(endDate);
                Calendar tempStart = Calendar.getInstance();//定义日期实例
                tempStart.setTime(beginDt);//设置日期起始时间
                Calendar tempEnd = Calendar.getInstance();
                tempEnd.setTime(endDt);
                tempEnd.add(Calendar.DAY_OF_YEAR, 1);
                List<String> dates = new ArrayList<String>();
                while (tempStart.before(tempEnd)) {
                    dates.add(CalendarUtil.dateToString(tempStart.getTime(),CalendarUtil.SDF_DEFAULT));
                    xData.add(CalendarUtil.dateToString(tempStart.getTime(),CalendarUtil.SDF_DEFAULT));
                    volume.add(0);
                    tempStart.add(Calendar.DAY_OF_YEAR, 1);
                }
                break;
        }
        map.put("legend",legend);
        map.put("diff",diff);
        map.put("xData",xData);
        map.put("volume",volume);
        map.put("cycle",cycle);

        return  map;
    }
}
